/***************************************************************************\
 * Copyright (C) by Keio University
 * GLSLShader.hpp created in 09 2011.
 * Mail : fdesorbi@hvrl.ics.keio.ac.jp
 *
 * GLSLShader.hpp is part of the HVRL Engine Library.
 *
 * The HVRL Engine Library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * The HVRL Engine Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
\***************************************************************************/

/*
 * Anti-doublon
 */
#ifndef __HVRL_GLSL_SHADER_HPP__
#define __HVRL_GLSL_SHADER_HPP__

/*
 * External Includes
 */
#include <GL/glew.h>
#include <list>

namespace hvrl
{

namespace glsl
{

/**
 * \brief check if shaders are available
 *
 * \author Francois de Sorbier
 * \return true if shaders are available, false otherwise
 */
bool checkAvailability(void);

/**
* \brief Compile a shader object
*
* The function requieres the ARB_shading_language_100 OpenGL extension.
*
* \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
* \author Francois de Sorbier
* \param object a shader object
*/
bool compile(GLuint object);


/** \brief Compile an array of shader objects
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param objects array of shader objects
 * \param nbobjects number of shader objects
 */
bool compile(GLuint * objects,const size_t& nbobjects);

/**
 * \brief Compile a list of shader objects
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param objects list of shader objects
 */
bool compile(const std::list<GLuint>& objects);

/**
 * \brief Link an array of compiled shader objects
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param objects array of compiled shader objects
 * \param nb number of shader objects
 * \return a program object linked with compiled shader objects
 */
GLuint link(GLuint* objects,const unsigned int& nb);

/**
 * \brief Link two compiled shader objects
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param object1 a compiled shader object
 * \param object2 a compiled shader object
 * \return a program object linked with compiled shader objects
 */
GLuint link(const GLuint& object1, const GLuint& object2);

/**
 * \brief Link a list of compiled shader objects
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * \warning Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param objects list of compiled shader objects
 * \return a program object linked with compiled shader objects
 */
GLuint link(const std::list<GLuint>& objects);

/**
 * \brief Load a GLSL file and create the related shader object. It can be a vertex, geometry or fragment shader.
 *
 * A vertex file has the extension ".vert" or contains the word "vertex".
 * A fragment file has the extension ".frag" or contains the word "fragment" or "pixel".
 * A fragment file has the extension ".geom" or contains the word "geometry".
 *
 * The function return 0 if the loading have failed
 * \author Francois de Sorbier
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 * The function requieres the ARB_geometry_shader4 OpenGL extension to load geometry shader files.
 *
 * Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 *
 * \param filename the filename of the file containing the GLSL code
 * \return GLuint the shader object created
 */
GLuint loadShader(const char * filename);

/**
 * \brief Load a vertex shader file and create the vertex shader object.
 *
 * The function return 0 if the loading have failed
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 *
 * Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 *
 * \param filename the filename of the file containing the vertex shader code
 * \return GLuint the vertex shader object created
 */
GLuint loadVertexShader(const char * filename);

/**
 * \brief \brief Load a fragment shader file and create the fragment shader object.
 *
 * The function return 0 if the loading have failed
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 * \author Francois de Sorbier
 * \param filename the filename of the file containing the fragment shader code
 * \return GLuint the fragment shader object created
 */
GLuint loadFragmentShader(const char * filename);


#ifdef GL_ARB_geometry_shader4
/**
 * \brief Load a geometry shader file and create the geometry shader object.
 *
 * The function return 0 if the loading have failed
 *
 * The function requieres the ARB_shading_language_100 OpenGL extension.
 * The function requieres the ARB_geometry_shader4 OpenGL extension.
 *
 * Don't forget to create a valid OpenGL context and to call the function glewInit() before using this function.
 * \author Francois de Sorbier
 * \param filename the filename of the file containing the geometry shader code
 * \return GLuint the geometry shader object created
 */
GLuint loadGeometryShader(const char * filename);
#endif


}

}

/*
 * End of Anti-doublon
 */
#endif
